#include "Calculate.h"
#include "LanguageSymbols.h"
#include "WllString.h"
#include <cassert>
#include <algorithm>
using namespace Wll::Util;

//CHAR_SYMBOL => Symbols::CHAR
Symbols ToRemarkType(SymbolTypes type)
{
	const Symbols* targetType;

	if(type == SymbolTypes::CHAR_TYPE)
    {
        targetType = &Symbols::CHAR;
    }
	else if (type == SymbolTypes::INTEGER_TYPE)
    {
        targetType = &Symbols::INTEGER;
    }
	else if (type == SymbolTypes::LONG_TYPE)
    {
        targetType = &Symbols::LONG;
    }
	else if (type == SymbolTypes::FLOAT_TYPE)
    {
        targetType = &Symbols::FLOAT;
    }
	else if (type == SymbolTypes::DOUBLE_TYPE)
    {
        targetType = &Symbols::DOUBLE;
    }
	else if (type == SymbolTypes::STRING_TYPE)
    {
        targetType = &Symbols::STRING;
    }

	return *targetType;
}

//Symbols::CHAR => SymbolTypes::CHAR_TYPE
SymbolTypes ToEnumType(Symbols type)
{
	if(type == Symbols::CHAR)
	{
		return SymbolTypes::CHAR_TYPE;
	}
	else if(type == Symbols::INTEGER)
	{
		return SymbolTypes::INTEGER_TYPE;
	}
	else if(type == Symbols::LONG)
	{
		return SymbolTypes::LONG_TYPE;
	}
	else if(type == Symbols::FLOAT)
	{
		return SymbolTypes::FLOAT_TYPE;
	}
	else if(type == Symbols::DOUBLE)
	{
		return SymbolTypes::DOUBLE_TYPE;
	}
	else if(type == Symbols::STRING)
	{
		return SymbolTypes::STRING_TYPE;
	}
	else
	{
		return SymbolTypes::VOID_TYPE;
	}
}

//根據字符常量內容轉換爲對應類型的數值型變量值
Symbols CastToNumber(const vector<Symbols>& constant_symbols)
{
	string number_string;
	ToString(number_string, constant_symbols);
	SymbolTypes type = DetectNumType(number_string);
	return CastTo(type, number_string); 
}

//根據字符串內容檢測能轉換的數值類型
SymbolTypes DetectNumType(const string& number_string)
{
	bool have_see_point = false;
	int integer_part_len = 0;
	int float_part_len = 0;
	for(const char* c = number_string.c_str(); *c != '\0'; c++)
	{
		if(*c == '.')
		{
			if(!have_see_point)
			{
				have_see_point = true;
			}
			else
			{
				return SymbolTypes::STRING_TYPE;
			}
		}
		else if(isdigit(*c))
		{
			if(!have_see_point)
			{
				integer_part_len++;
			}
			else
			{
				float_part_len++;
			}
		}
		else
		{
			return SymbolTypes::STRING_TYPE;
		}
	}
	
	return (have_see_point?(float_part_len>=6?SymbolTypes::DOUBLE_TYPE:SymbolTypes::FLOAT_TYPE):(integer_part_len>=6?SymbolTypes::LONG_TYPE:SymbolTypes::INTEGER_TYPE));
}

//把字符常量串轉換爲對應的數值類型變量值
Symbols CastTo(SymbolTypes type, string s)
{
	assert(type == SymbolTypes::CHAR_TYPE
		|| type == SymbolTypes::INTEGER_TYPE
		|| type == SymbolTypes::LONG_TYPE
		|| type == SymbolTypes::FLOAT_TYPE
		|| type == SymbolTypes::DOUBLE_TYPE
		|| type == SymbolTypes::STRING_TYPE
	);
	
	if(type == SymbolTypes::INTEGER_TYPE)
    {
        int i;
        String2Int(s,i);
        return(Symbols(i));
    }
	else if (type == SymbolTypes::LONG_TYPE)
    {
        long l;
        String2Long(s,l);
        return(Symbols(l));
    }
	else if (type == SymbolTypes::FLOAT_TYPE)
    {
        float f;
        String2Float(s,f);
        return(Symbols(f));
    }
	else if (type == SymbolTypes::DOUBLE_TYPE)
    {
        double d;
        String2Double(s,d);
        return(Symbols(d));
    }
	else if (type == SymbolTypes::STRING_TYPE)
    {
        return(Symbols(SymbolTypes::STRING_TYPE, s.c_str()));
    }
	else
    {
		return Symbols();
	}	
}

Symbols CastTo(SymbolTypes type, const Symbols& value)
{
	assert(type == SymbolTypes::CHAR_TYPE
		|| type == SymbolTypes::INTEGER_TYPE
		|| type == SymbolTypes::LONG_TYPE
		|| type == SymbolTypes::FLOAT_TYPE
		|| type == SymbolTypes::DOUBLE_TYPE
		|| type == SymbolTypes::STRING_TYPE
	);
	
	return CastTo(ToRemarkType(type), value);
}

Symbols CastTo(const Symbols& targetType, const Symbols& value)
{
	assert(targetType.IsRemark());
	
	assert(targetType == Symbols::CHAR
		|| targetType == Symbols::INTEGER
		|| targetType == Symbols::LONG
		|| targetType == Symbols::FLOAT
		|| targetType == Symbols::DOUBLE
		|| targetType == Symbols::STRING
	);
	
	if(targetType == Symbols::CHAR)
	{
		//convert to char type
		assert(value.type == SymbolTypes::INTEGER_TYPE || value.type == SymbolTypes::CONSTANT_TYPE || value.type == SymbolTypes::CHAR_TYPE);
		if (value.type == SymbolTypes::INTEGER_TYPE)
		{
			return Symbols(SymbolTypes::CHAR_TYPE, char(value.i));
		}
		else if (value.type == SymbolTypes::CONSTANT_TYPE)
		{
			return Symbols(SymbolTypes::CHAR_TYPE, char(value.value));
		}
		else if (value.type == SymbolTypes::CHAR_TYPE)
		{
			return value;
		}
	} 
	else if(targetType == Symbols::INTEGER)
	{
		//convert to integer type
		assert(value.type == SymbolTypes::INTEGER_TYPE 
			|| value.type == SymbolTypes::CHAR_TYPE
			|| value.type == SymbolTypes::LONG_TYPE
			|| value.type == SymbolTypes::FLOAT_TYPE
			|| value.type == SymbolTypes::DOUBLE_TYPE
			|| value.type == SymbolTypes::STRING_TYPE
			|| value.type == SymbolTypes::COMPACT_TYPE
		);

		if(value.type == SymbolTypes::INTEGER_TYPE)
        {
            return (value);
        }
		else if (value.type == SymbolTypes::CHAR_TYPE)
        {
            return (Symbols(int(value.c)));
        }
		else if (value.type == SymbolTypes::LONG_TYPE)
        {
            return (Symbols(int(value.l)));
        }
		else if (value.type == SymbolTypes::FLOAT_TYPE)
        {
            return (Symbols(int(value.f)));
        }
		else if (value.type == SymbolTypes::DOUBLE_TYPE)
        {
            return (Symbols(int(value.d)));
        }
		else if (value.type == SymbolTypes::STRING_TYPE)
        {
            int i;
            String2Int(*(*(value.s)), i);
            return (Symbols(i));
        }
		else if (value.type == SymbolTypes::COMPACT_TYPE)
        {
            int i;
            String2Int(value.ToString(), i);
            return (Symbols(i));
        }
	}
	else if(targetType == Symbols::LONG)
	{
		//convert to long type
		assert(value.type == SymbolTypes::LONG_TYPE 
			|| value.type == SymbolTypes::CHAR_TYPE
			|| value.type == SymbolTypes::INTEGER_TYPE
			|| value.type == SymbolTypes::FLOAT_TYPE
			|| value.type == SymbolTypes::DOUBLE_TYPE
			|| value.type == SymbolTypes::STRING_TYPE
			|| value.type == SymbolTypes::COMPACT_TYPE
		);

        if(value.type == SymbolTypes::LONG_TYPE)
        {
            return (value);
        }
        else if (value.type == SymbolTypes::CHAR_TYPE)
        {
            return (Symbols(long(value.c)));
        }
        else if (value.type == SymbolTypes::INTEGER_TYPE)
        {
            return (Symbols(long(value.i)));
        }
        else if (value.type == SymbolTypes::FLOAT_TYPE)
        {
            return (Symbols(long(value.f)));
        }
        else if (value.type == SymbolTypes::DOUBLE_TYPE)
        {
            return (Symbols(long(value.d)));
        }
        else if (value.type == SymbolTypes::STRING_TYPE)
        {
            long l;
            String2Long(*(*(value.s)), l);
            return (Symbols(l));
        }
        else if (value.type == SymbolTypes::COMPACT_TYPE)
        {
            long l;
            String2Long(value.ToString(), l);
            return (Symbols(l));
        }
	}
	else if(targetType == Symbols::FLOAT)
	{
		//convert to float type
		assert(value.type == SymbolTypes::FLOAT_TYPE 
			|| value.type == SymbolTypes::CHAR_TYPE
			|| value.type == SymbolTypes::INTEGER_TYPE
			|| value.type == SymbolTypes::LONG_TYPE
			|| value.type == SymbolTypes::DOUBLE_TYPE
			|| value.type == SymbolTypes::STRING_TYPE
			|| value.type == SymbolTypes::COMPACT_TYPE
		);

        if(value.type == SymbolTypes::FLOAT_TYPE)
        {
            return (value);
        }
        else if (value.type == SymbolTypes::CHAR_TYPE)
        {
            return (Symbols(float(value.c)));
        }
        else if (value.type == SymbolTypes::INTEGER_TYPE)
        {
            return (Symbols(float(value.i)));
        }
        else if (value.type == SymbolTypes::LONG_TYPE)
        {
            return (Symbols(float(value.l)));
        }
        else if (value.type == SymbolTypes::DOUBLE_TYPE)
        {
            return (Symbols(float(value.d)));
        }
        else if (value.type == SymbolTypes::STRING_TYPE)
        {
            float f;
            String2Float(*(*(value.s)), f);
            return (Symbols(f));
        }
        else if (value.type == SymbolTypes::COMPACT_TYPE)
        {
            float f;
            String2Float(value.ToString(), f);
            return (Symbols(f));
        }
	}
	else if(targetType == Symbols::DOUBLE)
	{
		//convert to double type
		assert(value.type == SymbolTypes::DOUBLE_TYPE 
			|| value.type == SymbolTypes::CHAR_TYPE
			|| value.type == SymbolTypes::INTEGER_TYPE
			|| value.type == SymbolTypes::LONG_TYPE
			|| value.type == SymbolTypes::FLOAT_TYPE
			|| value.type == SymbolTypes::STRING_TYPE
			|| value.type == SymbolTypes::COMPACT_TYPE
		);

        if(value.type == SymbolTypes::DOUBLE_TYPE)
        {
            return (value);
        }
        else if (value.type == SymbolTypes::CHAR_TYPE)
        {
            return (Symbols(double(value.c)));
        }
        else if (value.type == SymbolTypes::INTEGER_TYPE)
        {
            return (Symbols(double(value.i)));
        }
        else if (value.type == SymbolTypes::LONG_TYPE)
        {
            return (Symbols(double(value.l)));
        }
        else if (value.type == SymbolTypes::FLOAT_TYPE)
        {
            return (Symbols(double(value.f)));
        }
        else if (value.type == SymbolTypes::STRING_TYPE)
        {
            double d;
            String2Double(*(*(value.s)), d);
            return (Symbols(d));
        }
        else if (value.type == SymbolTypes::COMPACT_TYPE)
        {
            double d;
            String2Double(value.ToString(), d);
            return (Symbols(d));
        }
	}
	else if(targetType == Symbols::STRING)
	{
		//convert to string type
		if(value.type == SymbolTypes::STRING_TYPE)
		{
			return(value);
		}
		else
		{
			return(Symbols(SymbolTypes::STRING_TYPE, value.ToString().c_str()));
		}
	}
	return Symbols();
}

Symbols CastTo(const Symbols& targetType, std::vector<Symbols>& values)
{
	assert(targetType.IsRemark());
	Symbols value(values[0]);
	
	assert(targetType == Symbols::CHAR
		|| targetType == Symbols::INTEGER
		|| targetType == Symbols::LONG
		|| targetType == Symbols::FLOAT
		|| targetType == Symbols::DOUBLE
		|| targetType == Symbols::STRING
	);
	
	if(value.type == SymbolTypes::CONSTANT_TYPE && !(targetType == Symbols::CHAR))
	{
		string s;
		ToString(s, values);
		return CastTo(ToEnumType(targetType), s);
	}
	else
	{
		return CastTo(targetType, value);
	}
}

Symbols CastTo(std::vector<Symbols>& values, bool treatConstantsAsNumber)
{
	assert(!values.empty());
	Symbols firstSymbol(values[0]);
	if (firstSymbol.IsConstant())
	{
		if(treatConstantsAsNumber)
		{
			return CastToNumber(values);
		}
		else
		{
			return CastTo(Symbols::STRING, values);
		}
	}
	else
	{
		return firstSymbol;
	}
}

Symbols Add(const Symbols& a, const Symbols& b)
{
	Symbols c(a);
	return AddTo(c,b);
}

const Symbols& AddTo(Symbols& a, const Symbols& b)
{
	assert(a.type == SymbolTypes::CHAR_TYPE
		|| a.type == SymbolTypes::INTEGER_TYPE
		|| a.type == SymbolTypes::LONG_TYPE
		|| a.type == SymbolTypes::FLOAT_TYPE
		|| a.type == SymbolTypes::DOUBLE_TYPE
		|| a.type == SymbolTypes::STRING_TYPE
	);
	
	assert(b.type == SymbolTypes::CHAR_TYPE
		|| b.type == SymbolTypes::INTEGER_TYPE
		|| b.type == SymbolTypes::LONG_TYPE
		|| b.type == SymbolTypes::FLOAT_TYPE
		|| b.type == SymbolTypes::DOUBLE_TYPE
		|| b.type == SymbolTypes::STRING_TYPE
	);
	
	Symbols c(b);
	if (a.type < c.type)
	{
		a = CastTo(c.type, a);
	}
	else if (a.type > c.type)
	{
		c = CastTo(a.type, c);
	}
	
	//a.type == c.type
	if (a.type == SymbolTypes::CHAR_TYPE)
    {
        a.c += c.c;
    }
	else if (a.type == SymbolTypes::INTEGER_TYPE)
    {
        a.i += c.i;
    }
	else if (a.type == SymbolTypes::LONG_TYPE)
    {
        a.l += c.l;
    }
	else if (a.type == SymbolTypes::FLOAT_TYPE)
    {
        a.f += c.f;
    }
	else if (a.type == SymbolTypes::DOUBLE_TYPE)
    {
        a.d += c.d;
    }
	else if (a.type == SymbolTypes::STRING_TYPE)
    {
        (*(*a.s)) = (*(*a.s)) + (*(*c.s));
    }
	
	return a;
}

Symbols operator-(const Symbols& a, const Symbols& b)
{
	Symbols c(a);
	return (c -= b);
}

const Symbols& operator-=(Symbols& a, const Symbols& b)
{
	assert(a.type == SymbolTypes::CHAR_TYPE
		|| a.type == SymbolTypes::INTEGER_TYPE
		|| a.type == SymbolTypes::LONG_TYPE
		|| a.type == SymbolTypes::FLOAT_TYPE
		|| a.type == SymbolTypes::DOUBLE_TYPE
	);
	
	assert(b.type == SymbolTypes::CHAR_TYPE
		|| b.type == SymbolTypes::INTEGER_TYPE
		|| b.type == SymbolTypes::LONG_TYPE
		|| b.type == SymbolTypes::FLOAT_TYPE
		|| b.type == SymbolTypes::DOUBLE_TYPE
	);
	
	Symbols c(b);
	if (a.type < c.type)
	{
		a = CastTo(c.type, a);
	}
	else if (a.type > c.type)
	{
		c = CastTo(a.type, c);
	}
	
	//a.type == c.type
	if (a.type == SymbolTypes::CHAR_TYPE)
    {
        a.c -= c.c;
    }
	else if (a.type == SymbolTypes::INTEGER_TYPE)
    {
        a.i -= c.i;
    }
	else if (a.type == SymbolTypes::LONG_TYPE)
    {
        a.l -= c.l;
    }
	else if (a.type == SymbolTypes::FLOAT_TYPE)
    {
        a.f -= c.f;
    }
	else if (a.type == SymbolTypes::DOUBLE_TYPE)
    {
		a.d -= c.d;
	}
	
	return a;
}

Symbols operator*(const Symbols& a, const Symbols& b)
{
	Symbols c(a);
	return (c *= b);
}

const Symbols& operator*=(Symbols& a, const Symbols& b) {
    assert(a.type == SymbolTypes::CHAR_TYPE
           || a.type == SymbolTypes::INTEGER_TYPE
           || a.type == SymbolTypes::LONG_TYPE
           || a.type == SymbolTypes::FLOAT_TYPE
           || a.type == SymbolTypes::DOUBLE_TYPE
    );

    assert(b.type == SymbolTypes::CHAR_TYPE
           || b.type == SymbolTypes::INTEGER_TYPE
           || b.type == SymbolTypes::LONG_TYPE
           || b.type == SymbolTypes::FLOAT_TYPE
           || b.type == SymbolTypes::DOUBLE_TYPE
    );

    Symbols c(b);
    if (a.type < c.type) {
        a = CastTo(c.type, a);
    } else if (a.type > c.type) {
        c = CastTo(a.type, c);
    }

    //a.type == c.type
    if (a.type == SymbolTypes::CHAR_TYPE)
    {
        a.c *= c.c;
    }
	else if (a.type == SymbolTypes::INTEGER_TYPE)
    {
        a.i *= c.i;
    }
	else if (a.type == SymbolTypes::LONG_TYPE)
    {
        a.l *= c.l;
    }
	else if (a.type == SymbolTypes::FLOAT_TYPE)
    {
        a.f *= c.f;
    }
	else if (a.type == SymbolTypes::DOUBLE_TYPE)
    {
		a.d *= c.d;
	}
	
	return a;
}

Symbols operator/(const Symbols& a, const Symbols& b)
{
	Symbols c(a);
	return (c /= b);
}

const Symbols& operator/=(Symbols& a, const Symbols& b)
{
	assert(a.type == SymbolTypes::CHAR_TYPE
		|| a.type == SymbolTypes::INTEGER_TYPE
		|| a.type == SymbolTypes::LONG_TYPE
		|| a.type == SymbolTypes::FLOAT_TYPE
		|| a.type == SymbolTypes::DOUBLE_TYPE
	);
	
	assert(b.type == SymbolTypes::CHAR_TYPE
		|| b.type == SymbolTypes::INTEGER_TYPE
		|| b.type == SymbolTypes::LONG_TYPE
		|| b.type == SymbolTypes::FLOAT_TYPE
		|| b.type == SymbolTypes::DOUBLE_TYPE
	);
	
	Symbols c(b);
	if (a.type < c.type)
	{
		a = CastTo(c.type, a);
	}
	else if (a.type > c.type)
	{
		c = CastTo(a.type, c);
	}
	
	//a.type == c.type
	if (a.type == SymbolTypes::CHAR_TYPE)
    {
        a.c /= c.c;
    }
	else if (a.type == SymbolTypes::INTEGER_TYPE)
    {
        a.i /= c.i;
    }
	else if (a.type == SymbolTypes::LONG_TYPE)
    {
        a.l /= c.l;
    }
	else if (a.type == SymbolTypes::FLOAT_TYPE)
    {
        a.f /= c.f;
    }
	else if (a.type == SymbolTypes::DOUBLE_TYPE)
    {
		a.d /= c.d;
	}
	
	return a;
}

Symbols operator%(const Symbols& a, const Symbols& b)
{
	Symbols c(a);
	return (c %= b);
}

const Symbols& operator%=(Symbols& a, const Symbols& b)
{
	assert(a.type == SymbolTypes::CHAR_TYPE
		|| a.type == SymbolTypes::INTEGER_TYPE
		|| a.type == SymbolTypes::LONG_TYPE
	);
	
	assert(b.type == SymbolTypes::CHAR_TYPE
		|| b.type == SymbolTypes::INTEGER_TYPE
		|| b.type == SymbolTypes::LONG_TYPE
	);
	
	Symbols c(b);
	if (a.type < c.type)
	{
		a = CastTo(c.type, a);
	}
	else if (a.type > c.type)
	{
		c = CastTo(a.type, c);
	}
	
	//a.type == c.type
	if (a.type == SymbolTypes::CHAR_TYPE)
    {
        a.c %= c.c;
    }
	else if (a.type == SymbolTypes::INTEGER_TYPE)
    {
        a.i %= c.i;
    }
	else if (a.type == SymbolTypes::LONG_TYPE)
    {
		a.l %= c.l;
	}
	
	return a;
}

bool Equal(const Symbols& a, const Symbols& b)
{
	assert(a.type == SymbolTypes::CHAR_TYPE
		|| a.type == SymbolTypes::INTEGER_TYPE
		|| a.type == SymbolTypes::LONG_TYPE
		|| a.type == SymbolTypes::FLOAT_TYPE
		|| a.type == SymbolTypes::DOUBLE_TYPE
	);
	
	assert(b.type == SymbolTypes::CHAR_TYPE
		|| b.type == SymbolTypes::INTEGER_TYPE
		|| b.type == SymbolTypes::LONG_TYPE
		|| b.type == SymbolTypes::FLOAT_TYPE
		|| b.type == SymbolTypes::DOUBLE_TYPE
	);
	
	Symbols c;
	if (a.type < b.type)
	{
		c = CastTo(b.type, a);
		return (c == b);
	}
	else if (a.type > b.type)
	{
		c = CastTo(a.type, b);
		return (a == c);
	}
	else
	{
		return (a == b);
	}
	
}

bool LessThan(const Symbols& a, const Symbols& b)
{
	assert(a.type == SymbolTypes::CHAR_TYPE
		|| a.type == SymbolTypes::INTEGER_TYPE
		|| a.type == SymbolTypes::LONG_TYPE
		|| a.type == SymbolTypes::FLOAT_TYPE
		|| a.type == SymbolTypes::DOUBLE_TYPE
	);
	
	assert(b.type == SymbolTypes::CHAR_TYPE
		|| b.type == SymbolTypes::INTEGER_TYPE
		|| b.type == SymbolTypes::LONG_TYPE
		|| b.type == SymbolTypes::FLOAT_TYPE
		|| b.type == SymbolTypes::DOUBLE_TYPE
	);
	
	Symbols c;
	if (a.type < b.type)
	{
		c = CastTo(b.type, a);
		return (c < b);
	}
	else if (a.type > b.type)
	{
		c = CastTo(a.type, b);
		return (a < c);
	}
	else
	{
		return (a < b);
	}
	
}

Symbols Encode(vector<Symbols>& value, bool force)
{
	if(value.size() == 1)
	{
		if (force)
		{
			Symbols symbol(SymbolTypes::COMPACT_TYPE);
			symbol.GetList().push_back(value[0]);
			return symbol;
		}
		else
		{
			return value[0];
		}
	}
	else
	{
		Symbols symbol(SymbolTypes::COMPACT_TYPE);
		//symbol.GetList() = value;
		for(vector<Symbols>::const_iterator i = value.begin(); i != value.end(); i++)
		{
			symbol.GetList().push_back(*i);
		}
		return symbol;
	}
}

vector<Symbols> Decode(Symbols& symbol)
{
	vector<Symbols> value;
	if(symbol.type == SymbolTypes::COMPACT_TYPE)
	{
		//value = symbol.GetList();
		for(vector<Symbols>::const_iterator i = symbol.GetList().begin(); i != symbol.GetList().end(); i++)
		{
			value.push_back(*i);
		}
	}
	else
	{
		value.push_back(symbol);
	}
	return value;
}

void Flat(const Symbols& compacted_symbol, vector<Symbols>& flated_symbols)
{
	vector<Symbols> flat_stack;
	flat_stack.push_back(compacted_symbol);

	while (!flat_stack.empty())
	{
		Symbols symbol = flat_stack.back();
		flat_stack.pop_back();

		if (symbol.type == SymbolTypes::COMPACT_TYPE)
		{
			for (vector<Symbols>::const_reverse_iterator i = symbol.GetList().rbegin(); i != symbol.GetList().rend(); i++)
			{
				flat_stack.push_back(*i);
			}
		}
		else
		{
			flated_symbols.push_back(symbol);
		}
	}
}

void Flat(const vector<Symbols>& symbols, vector<Symbols>& flated_symbols)
{
	vector<Symbols> flat_stack(symbols.size());
	copy(symbols.rbegin(), symbols.rend(), flat_stack.begin());

	while (!flat_stack.empty())
	{
		Symbols symbol = flat_stack.back();
		flat_stack.pop_back();

		if (symbol.type == SymbolTypes::COMPACT_TYPE)
		{
			for (vector<Symbols>::const_reverse_iterator i = symbol.GetList().rbegin(); i != symbol.GetList().rend(); i++)
			{
				flat_stack.push_back(*i);
			}
		}
		else
		{
			flated_symbols.push_back(symbol);
		}
	}
}
